<html>
<head><meta charset="utf-8"><title>capture type · project-deref-patterns · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/index.html">project-deref-patterns</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html">capture type</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="245109692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245109692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245109692">(Jul 06 2021 at 23:08)</a>:</h4>
<blockquote>
<p>I think the open questions are around the exact behavior on capture (e.g., marching on String with a @ "foo", does that give you a: String, a: &amp;str, or a: &amp;String?)</p>
</blockquote>



<a name="245109851"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245109851" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245109851">(Jul 06 2021 at 23:11)</a>:</h4>
<p>IMO, if there is an @, then it seems intuitive that the type of the variable should match the type of the pattern, i.e., a: &amp;str in the example. Assuming we are matching a value with type &amp;String, then a variable without an @ binding should have the most general type (which also preserves back compat), i.e., a: &amp;String.</p>



<a name="245109886"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245109886" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245109886">(Jul 06 2021 at 23:11)</a>:</h4>
<p>What are the arguments for a to have a String type rather than a str type in the @ case?</p>



<a name="245109963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245109963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245109963">(Jul 06 2021 at 23:12)</a>:</h4>
<p>I believe the primary argument was consistency between the raw binding and the constrained binding.</p>



<a name="245110022"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245110022" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245110022">(Jul 06 2021 at 23:13)</a>:</h4>
<p>So, </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">match</span><span class="w"> </span><span class="o">&amp;</span><span class="n">string</span><span class="p">{</span><span class="w"></span>
<span class="w">   </span><span class="n">x</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="s">"foo"</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="cm">/* x has type &amp;str here*/</span><span class="w"></span>
<span class="w">   </span><span class="n">x</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="cm">/* x has type &amp;String here*/</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="245110650"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245110650" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245110650">(Jul 06 2021 at 23:22)</a>:</h4>
<p>Is that an implementation concern, or a 'least surprise for the user' concern?</p>



<a name="245110847"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245110847" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245110847">(Jul 06 2021 at 23:26)</a>:</h4>
<p>I think user surprise would be my expectation. That said, "forcing" the less general type on the user (str in this case) seems a little awkward</p>



<a name="245110910"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245110910" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245110910">(Jul 06 2021 at 23:26)</a>:</h4>
<p>As long as it's possible to control which one you get with additional annotations, it seems logical to just pick an option and use it consistently</p>



<a name="245110928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245110928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245110928">(Jul 06 2021 at 23:27)</a>:</h4>
<p>I don't think there's a reason to let you have that control in the binding</p>



<a name="245110937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245110937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245110937">(Jul 06 2021 at 23:27)</a>:</h4>
<p>The original type is the least restrictive</p>



<a name="245111002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245111002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245111002">(Jul 06 2021 at 23:28)</a>:</h4>
<p>IMO assigning types from the outside in gives a better result here</p>



<a name="245111030"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245111030" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245111030">(Jul 06 2021 at 23:28)</a>:</h4>
<p>and you could get the other type with <code>&amp;*(x @ "foo") =&gt; ...</code> or such</p>



<a name="245111507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245111507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245111507">(Jul 06 2021 at 23:36)</a>:</h4>
<p>Given that the more general type can always be coerced to the less general one, it seems unnecessary to have the option to annotate</p>



<a name="245111545"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245111545" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nick Cameron <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245111545">(Jul 06 2021 at 23:37)</a>:</h4>
<p>As a user, I’m not sure if it is more surprising for the type to not match the pattern or for the presence of a pattern to affect the type</p>



<a name="245445407"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/281601-project-deref-patterns/topic/capture%20type/near/245445407" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/281601-project-deref-patterns/topic/capture.20type.html#245445407">(Jul 09 2021 at 13:48)</a>:</h4>
<p><span class="user-mention silent" data-user-id="256841">Nick Cameron</span> <a href="#narrow/stream/281601-project-deref-patterns/topic/capture.20type/near/245109851">said</a>:</p>
<blockquote>
<p>IMO, if there is an @, then it seems intuitive that the type of the variable should match the type of the pattern, i.e., a: &amp;str in the example. Assuming we are matching a value with type &amp;String, then a variable without an @ binding should have the most general type (which also preserves back compat), i.e., a: &amp;String.</p>
</blockquote>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">_check</span><span class="w"> </span><span class="p">(</span><span class="n">x</span>: <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="p">)</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">y</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">assert!</span><span class="p">(</span><span class="n">y</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="kc">true</span><span class="p">)),</span><span class="w"></span>
<span class="w">        </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p><strong>already</strong> yields:</p>
<div class="codehilite" data-code-language="Text only"><pre><span></span><code>error[E0308]: mismatched types
 --&gt; src/lib.rs:4:45
  |
4 |         y @ Some(true) =&gt; assert!(y == Some(true)),
  |                                             ^^^^
  |                                             |
  |                                             expected `&amp;bool`, found `bool`
  |                                             help: consider borrowing here: `&amp;true`
</code></pre></div>
<ul>
<li><a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=b2de486225ce0fa0e335431e8a5b2cab">Playground</a></li>
</ul>
<p>This problem was introduced with match binding modes / match ergonomics, so I just want to warn against making other such mistakes in the name of sugar: consistency ought to be more important than excessive sugar / terseness, as shown by C++ footguns.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>